package com.yuyuan.blog.quartz;

import com.yuyuan.blog.domain.po.BlogDaily;
import com.yuyuan.blog.mapper.DailyBlogMapper;
import com.yuyuan.common.utils.RedisConstants;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

@Component
public class AlphaJob implements Job {
    private static final Logger logger = LoggerFactory.getLogger(AlphaJob.class);

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DailyBlogMapper dailyBlogMapper;

    private static final Date epoch;

    static {
        try {
            epoch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2024-01-01 00:00:00");
        } catch (ParseException e) {
            throw new RuntimeException("初始化纪元失败！", e);
        }
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String redisKey = RedisConstants.getPostScoreKey();
        BoundSetOperations operations = redisTemplate.boundSetOps(redisKey);

        if (operations.size() == 0) {
            logger.info("[任务取消] 没有需要刷新的帖子！");
            return;
        }

        logger.info("[任务开始] 正在刷新帖子分数！" + operations.size());
        while (operations.size() > 0) {
            this.refresh((Long) operations.pop());
        }
        logger.info("[任务结束] 帖子分数刷新完毕！");
    }

    private void refresh(Long blogId) {
        BlogDaily blogDaily = dailyBlogMapper.selectById(blogId);

        // 评论数量
        int commentCount = blogDaily.getComments();
        // 点赞数量
        int likeCount = blogDaily.getLikes();
        // 帖子时间
        LocalDateTime createTime = blogDaily.getCreateTime();
        // 转换为 Date
        Date createDate = Date.from(createTime.atZone(ZoneId.systemDefault()).toInstant());
        // 计算权重
        double w = commentCount * 10L + likeCount * 3L;
        // 分数 = 帖子权重 + 距离天数
        double score = Math.log10(Math.max(w, 1))
                + (createDate.getTime() - epoch.getTime()) / (1000.0 * 3600 * 24);

        // 更新帖子分数
        blogDaily.setScore((int) score);
        dailyBlogMapper.updateById(blogDaily);
    }
}
